<?php

namespace common;

use common\dict\NumberDict;
use common\models\db\Oplog;
use common\models\search\ModelSearch;
use common\utils\General;
use PhpOffice\PhpSpreadsheet\Cell\DataType;
use yii\data\ActiveDataProvider;
use yii\db\ActiveQuery;
use yii\rest\ActiveController;
use yii\web\ServerErrorHttpException;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;

/**
 *
 */
abstract class BaseActiveController extends ActiveController
{
    public $serializer = [
        'class' => 'yii\rest\Serializer',
        'collectionEnvelope' => 'items',
    ];

    public $searchModelClass;

    protected $defaultPageSize = 10;

    public $moduleName;

    public function afterAction($action, $result)
    {
        $opType = '';
        switch ($action->id) {
            case 'create':
                $opType = '添加';
                break;
            case 'update':
                $opType = '修改';
                break;
            case 'delete':
            case 'delete-items':
                $opType = '删除';
                break;
        }
        $user = \Yii::$app->user->getIdentity();
        if ($user && $opType) {
            $logData = [
                'user_id' => $user->user_id,
                'user_name' => $user->user_name,
                'log_type' => 1,
                'op_type' => $opType,
                'op_desc' => $this->moduleName . $opType . '数据。',
                'content' => json_encode(\Yii::$app->getRequest()->getBodyParams(), JSON_UNESCAPED_UNICODE)
            ];
            Oplog::opLog($logData);
        }

        return parent::afterAction($action, $result); // TODO: Change the autogenerated stub
    }

    public function actions()
    {
        $actions = parent::actions();
        unset($actions['index']);
        return $actions;
    }

    public function actionIndex()
    {
        if ($this->searchModelClass) {
            $searchModel = $this->createSearchModel();
            $dataProvider = $searchModel->search(\Yii::$app->request->queryParams);
        } else {
            $query = $this->getQuery(\Yii::$app->request->queryParams);
            $dataProvider = new ActiveDataProvider([
                'query' => $query
            ]);
        }
        $dataProvider->pagination = [
            'defaultPageSize' => $this->defaultPageSize,
            'pageSizeParam' => 'page_size',
            'pageSizeLimit' => [0, 100],
        ];
        return $dataProvider;
    }

    /**
     * @param $ids
     * @throws ServerErrorHttpException
     */
    public function actionDeleteItems($ids)
    {
        $modelClass = $this->modelClass;
        $key = $modelClass::primaryKey()[0];
        if (!$modelClass::deleteAll("{$key} in ($ids)")) {
            throw new ServerErrorHttpException('Failed to delete the object for unknown reason.');
        }
        \Yii::$app->getResponse()->setStatusCode(204);
    }

    /**
     * @throws \PhpOffice\PhpSpreadsheet\Exception
     * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
     */
    public function actionExport()
    {
        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        header('Content-Disposition: attachment;filename="数据导出.xlsx"');
        header('Cache-Control: max-age=0');

        $dataProvider = $this->actionIndex();
        $models = $dataProvider->getModels();
        $spreadsheet = new Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet();

        $exportFields = $this->getExportFields();
        $width = count($exportFields);
        for ($i = 0; $i < $width; $i++) {
            $coordinate = chr(65 + $i) . "1";
            $sheet->getCell($coordinate)->getStyle()->getFont()->setBold(true);
            $sheet->setCellValue($coordinate, $exportFields[$i]['name']);
        }

        $dict = NumberDict::DATA[NumberDict::KEY_MAP[$this->modelClass]];
        foreach ($models as $k => $model) {
            for ($i = 0; $i < $width; $i++) {
                $coordinate = chr(65 + $i) . ($k + 2);
                $key = $exportFields[$i]['key'];
                $sheet->getCell($coordinate)->setDataType(DataType::TYPE_STRING2);
                if (!isset($dict[$key])) {
                    $value = $model[$key];
                } else {
                    $value = NumberDict::getNumberName($model[$key], $dict[$key]);
                }
                $sheet->setCellValue($coordinate, $value . "\t");
            }
        }

        $writer = new Xlsx($spreadsheet);
        $writer->save('php://output');
    }

    /**
     * @param array $params
     * @return ActiveQuery the newly created [[ActiveQuery]] instance.
     */
    protected function getQuery(array $params)
    {
        throw new \RuntimeException("unsupported");
    }

    protected function getExportFields()
    {
        return [];
    }

    /**
     * @return ModelSearch
     */
    protected function createSearchModel()
    {
        return new $this->searchModelClass();
    }

    /**
     * @param $list
     * @param string $fileNmae
     * @param int $test
     * @throws \PhpOffice\PhpSpreadsheet\Exception
     * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
     */
    public function actionExport2($list, $fileNmae = '数据导出', $test = 0)
    {
        set_time_limit(0);
        if (!$test) {
            header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
            header('Content-Disposition: attachment;filename="' . $fileNmae . '.xlsx"');
            header('Cache-Control: max-age=0');
        }
        $spreadsheet = new Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet();

        $exportFields = $this->getExportFields();
        $width = count($exportFields);
        for ($i = 0; $i < $width; $i++) {
            $coordinate = chr(65 + $i) . "1";
            $sheet->getCell($coordinate)->getStyle()->getFont()->setBold(true);
            $sheet->setCellValue($coordinate, $exportFields[$i]['name']);
        }

        foreach ($list as $k => $item) {
            for ($i = 0; $i < $width; $i++) {
                $coordinate = chr(65 + $i) . ($k + 2);
                $key = $exportFields[$i]['key'];

                $value = $item[$key];
                $sheet->setCellValue($coordinate, $value . "\t");
                $sheet->setCellValueExplicit($coordinate, isset($exportFields[$i]['type']) ? $value : $value . "\t", isset($exportFields[$i]['type']) ? $exportFields[$i]['type'] : DataType::TYPE_STRING2);
            }
        }
        ob_end_clean();
        $writer = new Xlsx($spreadsheet);
        $writer->save('php://output');
    }

    /**
     * @param $list
     * @param string $fileNmae
     * @throws \PhpOffice\PhpSpreadsheet\Exception
     * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
     */
    public function actionExport3($list, $fileNmae = '数据导出')
    {
        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        header('Content-Disposition: attachment;filename="' . $fileNmae . '.xlsx"');
        header('Cache-Control: max-age=0');

        $spreadsheet = new Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet();

        $exportFields = $this->getExportFields();
        $width = count($exportFields);
        for ($i = 0; $i < $width; $i++) {
            $coordinate = chr(65 + $i) . "1";
            $sheet->getCell($coordinate)->getStyle()->getFont()->setBold(true);
            $sheet->setCellValue($coordinate, $exportFields[$i]['name']);
        }

        foreach ($list as $k => $item) {
            for ($i = 0; $i < $width; $i++) {
                $coordinate = chr(65 + $i) . ($k + 2);
                $key = $exportFields[$i]['key'];
                $sheet->getCell($coordinate)->setDataType(DataType::TYPE_STRING2);

                $value = $item[$key];

                $sheet->setCellValue($coordinate, General::filterEmoji2($value) . "\t");
            }
        }
        $writer = new Xlsx($spreadsheet);
        $writer->save('php://output');
    }
}